package com.zx.sdk.util

import com.google.gson.Gson
import com.zx.sdk.ZxSDK
import com.zx.sdk.model.AdInfo
import com.zx.sdk.model.EventInfo
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response
import java.io.IOException
import java.util.Random

/**
 * 事件上报器
 * action 字段
 * fetch = 请求广告位
 * loaded = 广告位已填充
 * click = 广告位点击
 * expose = 广告位曝光
 * reward = 获得收益
 * 只有 reward 才需要传递 cpm
 */
object ZxActionReporter {
    private var started = false // 记录是否已经开始上报
    private const val KEY_REPORT_DATA = "KEY_REPORT_DATA_"

    /**
     * 记录事件在缓冲区
     */
    fun record(action: String, adInfo: AdInfo, cpm: String) {
        if (Random().nextInt(100) + 1 > ConfigHelper.getEvent_sample_rate()) {// 大于采样率则不记录
            return
        }
        val time = System.currentTimeMillis()
        // 准备要记录的数据
        val eventInfo = EventInfo(
            action,
            ZxSDK.getAppId(),
            adInfo.pid,
            adInfo.billType,
            adInfo.display,
            adInfo.league,
            adInfo.mapAppid,
            adInfo.mapPid,
            cpm, "${time / 1000}"
        )
        // 准备Key 前缀+行为+appid+pid+时间戳
        val key = "$KEY_REPORT_DATA${action}_${adInfo.mapAppid}_${adInfo.mapPid}_$time"
        // 缓存至SP
        SPHelper.put(key, Gson().toJson(eventInfo))
        LogHelper.d("ZxActionReporter", "记录Key", key)
    }

    /**
     *启动事件上报器
     */
    fun start() {
        if (started) {// 防止重复启动
            return
        }
        started = true
        startReport()
    }

    /**
     *开始上报
     */
    private fun startReport() {
        Thread {// 启动单独线程
            while (true) {
                val reportData = prepareReportData()
                if (reportData.isNotEmpty()) {// 检查如果有数据才上报
                    // 上报接口，重试2次
                    HttpHelper.retryPostJSON(
                        "https://event.ssp-api.yctourism.com/api/client/batch",
                        reportData,
                        object : Callback {
                            override fun onFailure(call: Call, e: IOException) {

                            }

                            override fun onResponse(call: Call, response: Response) {

                            }
                        }
                    )
                }
                Thread.sleep(60 * 1000)// 每一分钟检查上报一次
            }
        }.start()
    }

    /**
     *准备要上报的数据
     */
    private fun prepareReportData(): String {
        val reportData = arrayListOf<EventInfo>()
        SPHelper.getAll().forEach {
            if (it.key.startsWith(KEY_REPORT_DATA)) {// 如果是需要上报的数据才处理
                try {
                    SPHelper.remove(it.key)// 从缓存中移除
                    val eventInfo = Gson().fromJson(it.value as String, EventInfo::class.java)
                    if ((System.currentTimeMillis() / 1000) - eventInfo.produceTime.toLong() <= 3 * 60) {// 3分钟以内的才上报,以秒计算
                        reportData.add(eventInfo)
                    }
                } catch (e: Throwable) {
                    LogHelper.e("prepareReportData", e)
                }
            }
        }
        if (reportData.isEmpty()) {
            return ""
        }
        return Gson().toJson(reportData)
    }
}